home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Games / SprocketInvaders / Source / CD_Utils.c < prev    next >
Encoding:
Text File  |  2000-09-28  |  10.4 KB  |  526 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        CD_Utils.c
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Version:    xxx put version here xxx
  7.  
  8.     Copyright:    © 1999 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     File Ownership:
  11.  
  12.         DRI:                xxx put dri here xxx
  13.  
  14.         Other Contact:        xxx put other contact here xxx
  15.  
  16.         Technology:            xxx put technology here xxx
  17.  
  18.     Writers:
  19.  
  20.         (cjd)    Chris De Salvo
  21.  
  22.     Change History (most recent first):
  23.  
  24.        <SP1>     1/29/99    cjd        first checked in
  25. */
  26.  
  27. //•    ——————————————————————————————————————————————————————————————————————————————————————————    •
  28. //•
  29. //•    Copyright © 1997 Apple Computer, Inc., All Rights Reserved
  30. //•
  31. //•
  32. //•        You may incorporate this sample code into your applications without
  33. //•        restriction, though the sample code has been provided "AS IS" and the
  34. //•        responsibility for its operation is 100% yours.  However, what you are
  35. //•        not permitted to do is to redistribute the source as "DSC Sample Code"
  36. //•        after having made changes. If you're going to re-distribute the source,
  37. //•        we require that you make it clear in the source that the code was
  38. //•        descended from Apple Sample Code, but that you've made changes.
  39. //•
  40. //•        Authors:
  41. //•            Chris De Salvo        <mailto:desalvo@apple.com>
  42. //•
  43. //•    ——————————————————————————————————————————————————————————————————————————————————————————    •
  44.  
  45. //•    ——————————————————————————————    Includes
  46.  
  47. #include <Devices.h>
  48. #include <Errors.h>
  49. #include <MacTypes.h>
  50. #include <StringCompare.h>
  51. #include <ToolUtils.h>
  52.  
  53. #include <string.h>                    //•    For memset()
  54.  
  55. #include "CD_Utils.h"
  56.  
  57. //•    ——————————————————————————————    Private Definitions
  58.  
  59. #define kCDDriverName                "\p.AppleCD"
  60.  
  61. //•    ——————————————————————————————    Private Types
  62.  
  63. //•    CD Driver csCodes
  64. enum
  65. {
  66.     csDriveStatus                =    8,
  67.     csReadTOC                    =    100,
  68.     csReadQ                        =    101,
  69.     csAudioTrackSearch            =    103,
  70.     csPlayAudio                    =    104,
  71.     csAudioStop                    =    106,
  72.     csAudioStatus                =    107,
  73.     csAudioVolume                =    109,
  74.     csGetSpindleSpeed            =    113
  75. };
  76.  
  77. //•    CD addressing types
  78. enum
  79. {
  80.     addressLBS,
  81.     addressMIN_SEC_FRAME,
  82.     addressTrack
  83. };
  84.  
  85. #pragma options align=mac68k
  86. typedef struct AudioStatusRec
  87. {
  88.     QElemPtr    qLink;
  89.     SInt16        qType;
  90.     SInt16        ioTrap;
  91.     Ptr            ioCmdAddr;
  92.     ProcPtr        ioCompletion;
  93.     OSErr        ioResult;
  94.     StringPtr    ioNamePtr;
  95.     SInt16        ioVRefNum;
  96.     SInt16        ioRefNum;
  97.     SInt16        csCode;
  98.     struct
  99.     {
  100.         Byte    audioStatus;
  101.         Byte    playMode;
  102.         Byte    cntlField;
  103.         Byte    minutes;
  104.         Byte    seconds;
  105.         Byte    frames;
  106.     } csParam;
  107. } AudioStatusRec, *AudioStatusRecPtr;
  108. #pragma options align=reset
  109.  
  110. //•    ——————————————————————————————    Private Variables
  111.  
  112. static Boolean    gCDInited = false;
  113.  
  114. static SInt16    gCDDriverRef = 0;
  115. static SInt16    gCurrentTrack = 0;
  116.  
  117. static ParamBlockRec    gPlayParamBlock;
  118. static ParamBlockRec    gStopParamBlock;
  119.  
  120. //•    ——————————————————————————————    Private Functions
  121.  
  122. static UInt32 NumToBCD(UInt16 theNum);
  123. static void CD_ClearParamBlock(ParamBlockRec *inPB);
  124.  
  125. //•    ——————————————————————————————    Public Variables
  126.  
  127. //•    ————————————————————    CD_Open
  128.  
  129. OSErr
  130. CD_Open(void)
  131. {
  132. OSErr    theErr;
  133.  
  134.     theErr = OpenDriver(kCDDriverName, &gCDDriverRef);
  135.  
  136.     if (noErr == theErr)
  137.         gCDInited = true;
  138.  
  139.     //•    Zero this out so that the ioResult field is inited
  140.     CD_ClearParamBlock(&gPlayParamBlock);
  141.         
  142.     return (theErr);
  143. }
  144.  
  145. //•    ————————————————————    CD_GetSpeed
  146.  
  147. SInt16
  148. CD_GetSpeed(void)
  149. {
  150. OSErr            theErr;
  151. ParamBlockRec    thePB;
  152.  
  153.     if (false == gCDInited)
  154.         return (0);
  155.  
  156.     CD_ClearParamBlock(&thePB);
  157.  
  158.     thePB.cntrlParam.ioCRefNum = gCDDriverRef;
  159.     thePB.cntrlParam.csCode = csGetSpindleSpeed;
  160.     
  161.     theErr = PBControlSync(&thePB);
  162.  
  163.     if (noErr != theErr)
  164.         return (-1);
  165.  
  166.     return (thePB.cntrlParam.csParam[0]);
  167. }
  168.  
  169. //•    ————————————————————    CD_PlayAudioTrack
  170.  
  171. OSErr
  172. CD_PlayAudioTrack(UInt8 trackNumber, UInt8 playMode, Boolean inAsync)
  173. {
  174. ParamBlockRec    *thePB = &gPlayParamBlock;
  175.  
  176.     if (false == gCDInited)
  177.         return (paramErr);
  178.  
  179.     CD_ClearParamBlock(thePB);
  180.  
  181.     gCurrentTrack = trackNumber;
  182.  
  183.     thePB->cntrlParam.ioCRefNum = gCDDriverRef;                        //•    CD driver ref num
  184.     thePB->cntrlParam.csCode = csPlayAudio;                            //•    csCode to seek and play audio selection
  185.     
  186.     thePB->cntrlParam.csParam[0] = addressTrack;                    //•    Use track number addressing
  187.     thePB->cntrlParam.csParam[1] = 0;                                //•    High word of Track in BCD
  188.     thePB->cntrlParam.csParam[2] = LoWord(NumToBCD(trackNumber));    //•    Low word of Track in BCD
  189.     thePB->cntrlParam.csParam[3] = 0;                                //•    This is a start position
  190.     thePB->cntrlParam.csParam[4] = playMode;
  191.     
  192.     if (true == inAsync)
  193.     {
  194.         CD_WaitOnPlayAsyncCalls();
  195.         return (PBControlAsync(thePB));
  196.     }
  197.  
  198.     return (PBControlSync(thePB));
  199. }
  200.  
  201. //•    ————————————————————    CD_StopAudioTrack
  202.  
  203. OSErr
  204. CD_StopAudioTrack(Boolean inAsync)
  205. {
  206. ParamBlockRec    *thePB = &gStopParamBlock;
  207.  
  208.     if (false == gCDInited)
  209.         return (paramErr);
  210.  
  211.     CD_ClearParamBlock(thePB);
  212.     
  213.     thePB->cntrlParam.ioCRefNum = gCDDriverRef;                        //•    CD driver ref num
  214.     thePB->cntrlParam.csCode = csAudioStop;
  215.     
  216.     if (true == inAsync)
  217.     {
  218.         CD_WaitOnStopAsyncCalls();
  219.         return (PBControlAsync(thePB));
  220.     }
  221.  
  222.     return (PBControlSync(thePB));
  223. }
  224.  
  225. //•    ————————————————————    NumToBCD
  226.  
  227. static UInt32
  228. NumToBCD(UInt16 theNum)
  229. {
  230. UInt32    theBCD;
  231.  
  232.     theBCD = 0x0000;
  233.     
  234.     //•    Get the digits
  235.     theBCD |= theNum % 10;
  236.     theNum /= 10;
  237.  
  238.     //•    Get the tens
  239.     theBCD |= (theNum % 10) << 4;
  240.     theNum /= 10;
  241.     
  242.     //•    Get the hundreds
  243.     theBCD |= (theNum % 10) << 8;
  244.     theNum /= 10;    
  245.  
  246.     //•    Get the thousands
  247.     theBCD |= (theNum % 10) << 12;
  248.     
  249.     return (theBCD);
  250. }
  251.  
  252. //•    ————————————————————    BCDToNum
  253.  
  254. static SInt16
  255. BCDToNum(UInt8 bcd)
  256. {
  257. UInt8    place;
  258. SInt16    num = 0;
  259.     
  260.     place = bcd & 0x0F;                                    //•    Get the first 10 bits
  261.     num += place;
  262.     
  263.     place = (bcd >> 4) & 0x0F;
  264.     num += (place * 10);
  265.     
  266.     return (num);
  267. }
  268.  
  269. //•    ————————————————————    CD_GetCurrentAudioTrack
  270.  
  271. OSErr
  272. CD_GetCurrentAudioTrack(SInt16 *theTrack)
  273. {
  274. OSErr            theErr;
  275. ParamBlockRec    thePB;
  276.  
  277.     if (false == gCDInited)
  278.         return (paramErr);
  279.  
  280.     CD_ClearParamBlock(&thePB);
  281.     
  282.     thePB.cntrlParam.ioCRefNum = gCDDriverRef;                //•    CD driver ref num
  283.     thePB.cntrlParam.csCode = csReadQ;                        //•    Get the position of the optical pickup
  284.     
  285.     theErr = PBControlSync(&thePB);
  286.     
  287.     *theTrack =  BCDToNum(thePB.cntrlParam.csParam[0] & 0xFF);    //•    Return the current track number
  288.  
  289.     return (theErr);
  290. }
  291.  
  292. //•    ——————————————————————————————    CD_IsFileOnCD
  293.  
  294. IsOnCDResult
  295. CD_IsFileOnCD(SInt16 fileRef)
  296. {
  297. HParamBlockRec    volRec;
  298. DCtlHandle        devHandle;
  299. FCBPBRec        fileRec;
  300. OSErr            theErr;
  301.  
  302. StringPtr        driverName;
  303. StringPtr        cdDriverName = kCDDriverName;
  304.  
  305.     //•    Get information on this open file
  306.     fileRec.ioCompletion = nil;
  307.     fileRec.ioFCBIndx = 0;
  308.     fileRec.ioVRefNum = 0;
  309.     fileRec.ioRefNum = fileRef;
  310.     fileRec.ioNamePtr = nil;
  311.  
  312.     theErr = PBGetFCBInfoSync(&fileRec);
  313.  
  314.     if (noErr != theErr)
  315.         return (isOnCDErr);
  316.  
  317.     //•    Get information about the volume of this file
  318.     volRec.volumeParam.ioCompletion = nil;
  319.     volRec.volumeParam.ioNamePtr = nil;
  320.     volRec.volumeParam.ioVRefNum = fileRec.ioFCBVRefNum;
  321.     volRec.volumeParam.ioVolIndex = 0;
  322.     
  323.     theErr = PBHGetVInfoSync(&volRec);
  324.  
  325.     if (noErr != theErr)
  326.         return (isOnCDErr);
  327.  
  328.     //•    Get info on this drive's driver
  329.     devHandle = GetDCtlEntry(volRec.volumeParam.ioVDRefNum);
  330.  
  331.     if (nil == devHandle)
  332.         return (isOnCDErr);
  333.         
  334.     if ((**devHandle).dCtlFlags & (1 << dRAMBased))
  335.     {
  336.     Handle    driver;
  337.     
  338.         driver = (Handle) (**devHandle).dCtlDriver;
  339.         driverName = (StringPtr) (*driver + 18);
  340.     }
  341.     else
  342.     {
  343.         driverName = (StringPtr) ((**devHandle).dCtlDriver + 18);
  344.     }
  345.         
  346.     if (EqualString(driverName, cdDriverName, false, false) == true)
  347.         return (isOnCDTrue);
  348.  
  349.     return (isOnCDFalse);
  350. }
  351.  
  352. //•    ——————————————————————————————    CD_IsCDInserted
  353.  
  354. Boolean
  355. CD_IsCDInserted(void)
  356. {
  357. ParamBlockRec    params;
  358. OSErr            theErr;
  359.     
  360.     if (false == gCDInited)
  361.         return (false);
  362.  
  363.     CD_ClearParamBlock(¶ms);
  364.  
  365.     //•    On return from a drive status call the csParam fields have the same info
  366.     //•    as the regular disk driver DrvSts structure.  The fourth byte in that
  367.     //•    structure is true or false depending on whether or not a disk is in the drive.
  368.  
  369.     params.cntrlParam.ioVRefNum = 1;
  370.     params.cntrlParam.ioCRefNum = gCDDriverRef;
  371.     params.cntrlParam.csCode = csDriveStatus;
  372.     
  373.     theErr = PBStatusSync((ParmBlkPtr) ¶ms);
  374.  
  375.     if (noErr != theErr)
  376.         return (false);
  377.     
  378.     return (params.cntrlParam.csParam[1] & 0xFF);
  379. }
  380.  
  381. //•    ——————————————————————————————    CD_GetNumTracks
  382.  
  383. SInt16
  384. CD_GetNumTracks(void)
  385. {
  386. ParamBlockRec    params;
  387. OSErr            theErr;
  388. UInt8            lastTrack;
  389.     
  390.     if (false == gCDInited)
  391.         return (0);
  392.  
  393.     CD_ClearParamBlock(¶ms);
  394.     
  395.     params.cntrlParam.ioVRefNum = 1;
  396.     params.cntrlParam.ioCRefNum = gCDDriverRef;
  397.     params.cntrlParam.csCode = csReadTOC;
  398.     params.cntrlParam.csParam[0] = 1;            //•    Type 1 TOC lookup marker
  399.  
  400.     theErr = PBControlSync(¶ms);
  401.  
  402.     if (noErr != theErr)
  403.         return (0);
  404.  
  405.     lastTrack = params.cntrlParam.csParam[0] & 0xFF;
  406.  
  407.     //•    Return the number of tracks in decimal instead of BCD form
  408.     return (BCDToNum(lastTrack));
  409. }
  410.  
  411. //•    ——————————————————————————————    CD_IsCDPlaying
  412.  
  413. Boolean
  414. CD_IsCDPlaying(void)
  415. {
  416. ParamBlockRec    params;
  417. AudioStatusRec    *rec;
  418. OSErr            theErr;
  419.     
  420.     if (false == gCDInited)
  421.         return (false);
  422.  
  423.     params.cntrlParam.ioCompletion = nil;
  424.     params.cntrlParam.ioVRefNum = 1;
  425.     params.cntrlParam.ioCRefNum = gCDDriverRef;
  426.     params.cntrlParam.csCode = csAudioStatus;
  427.  
  428.     theErr = PBControlSync((ParmBlkPtr) ¶ms);
  429.  
  430.     if (noErr != theErr)
  431.         return (theErr);
  432.  
  433.     rec = (AudioStatusRec *) ¶ms;
  434.  
  435.     if (rec->csParam.audioStatus == 0)
  436.         return (true);
  437.  
  438.     return (false);
  439. }
  440.  
  441. //•    ————————————————————    CD_SetVolume
  442.  
  443. OSErr
  444. CD_SetVolume(UInt8 left, UInt8 right)
  445. {
  446. ParamBlockRec    thePB;
  447. UInt16    volume;
  448.  
  449.     if (false == gCDInited)
  450.         return (paramErr);
  451.  
  452.     CD_ClearParamBlock(&thePB);
  453.     
  454.     thePB.cntrlParam.ioCRefNum = gCDDriverRef;        //•    CD driver ref num
  455.     thePB.cntrlParam.csCode = csAudioVolume;
  456.  
  457.     volume = (left << 8) | right;
  458.     thePB.cntrlParam.csParam[0] = volume;
  459.     
  460.     return (PBControlSync(&thePB));
  461. }
  462.  
  463. //•    ————————————————————    CD_Eject
  464.  
  465. void
  466. CD_Eject(void)
  467. {
  468. OSErr            theErr;
  469. Str255            ioName;
  470. HVolumeParam    params;
  471. short            driverRef;
  472.  
  473.     memset(¶ms, 0, sizeof (params));
  474.  
  475.     params.ioNamePtr = ioName;
  476.     params.ioVolIndex = 0;
  477.     driverRef = gCDDriverRef;
  478.  
  479.     do
  480.     {
  481.         params.ioVolIndex++;
  482.         
  483.         theErr = PBHGetVInfoSync((HParmBlkPtr) ¶ms);
  484.  
  485.         if (theErr)
  486.             return;
  487.  
  488.     } while (params.ioVDRefNum != driverRef);
  489.  
  490.     theErr = PBUnmountVol((ParmBlkPtr) ¶ms);
  491.  
  492.     if (noErr == theErr)
  493.     {
  494.         params.ioVRefNum = params.ioVDrvInfo;        //•    get the drive number
  495.         theErr = PBEject((ParmBlkPtr) ¶ms);
  496.     }
  497. }
  498.  
  499. //•    ————————————————————    CD_ClearParamBlock
  500.  
  501. static void
  502. CD_ClearParamBlock(ParamBlockRec *inPB)
  503. {
  504.     memset(inPB, 0, sizeof (ParamBlockRec));
  505. }
  506.  
  507. //•    ————————————————————    CD_WaitOnPlayAsycCalls
  508.  
  509. void
  510. CD_WaitOnPlayAsyncCalls(void)
  511. {
  512.     while (1 == gPlayParamBlock.cntrlParam.ioResult)
  513.     {
  514.     }
  515. }
  516.  
  517. //•    ————————————————————    CD_WaitOnStopAsycCalls
  518.  
  519. void
  520. CD_WaitOnStopAsyncCalls(void)
  521. {
  522.     while (1 == gStopParamBlock.cntrlParam.ioResult)
  523.     {
  524.     }
  525. }
  526.